#pragma once

#include <hfsme/detail/HStaticTreeStructure.h>
#include <hfsme/detail/HStateHierarchyIterator.h>
#include <string>

namespace HFSME {

typedef int StateId;

class HStateMachineBase{
private:
	struct Implementation;
	Implementation *pImpl;
public:
	HStateMachineBase();
	virtual ~HStateMachineBase();
	void init (void);

protected:
	virtual detail::HStaticTreeStructure& getTheDerivedTreeStructure()=0;
};


template<typename ConcreteStateMachine>
class HStateMachine:HStateMachineBase
{
protected:
	virtual detail::HStaticTreeStructure& getTheDerivedTreeStructure()
	{
		return getTheTreeStructure();
	}
public:
	typedef ConcreteStateMachine state_machine;
	struct hierarchy{
		ConcreteStateMachine*	myself;
		enum { depth = 0 };
		hierarchy()
			:myself(0)
		{}
		void initialize(detail::HStateHierarchyIterator & iter)
		{
			myself=static_cast<ConcreteStateMachine*>(iter.getStateMachine());
		}
	};
	static detail::HStaticTreeStructure& getTheTreeStructure()
	{
		//assure that this variable is initialized before it's accessed
		//putting in into a static function
		static detail::HStaticTreeStructure theTreeStructure;
		return theTreeStructure;
	}
	template <typename SubStateType,bool isInitial=false>
	static int register_substate(const char * name)
	{
		assert(SubStateType::getOrSetStateId()==-1 && "Double Id Initialization");

		//set the state id
		SubStateType::getOrSetStateId()=getStateIdCounter()++;

		//set the name
		SubStateType::getOrSetName()=std::string(name);

		getTheTreeStructure().register_substate<SubStateType,isInitial>();
		return 1;
	}
	static StateId & getStateIdCounter(void)
	{
		static StateId theStateIdCounter=0;
		return theStateIdCounter;
	}


};





}  // namespace HFSME
